iT邦幫忙

3

[Nuxt Vue] Error status跳404頁面

Gary 2020-03-27 23:37:168762 瀏覽
  • 分享至 

  • xImage
  •  

用nuxt處理Eroor 404頁面的時候不小心踩到一個坑,因為當初幾乎用了一整天,整個人陷下去坑裡
所以索性就記個筆記,也順便讓其他人不要踩到坑

404 page

前言

一個頁面發生錯誤時,應該要顯示自製404或Error的頁面
而不是顯示官方的錯誤頁面

其實在我進公司前,前一個前端工程師有製作一個404頁面
但....當初用法完全錯誤啊!!!!~~~

錯誤作法(以部落格文章api為例)

輸入值

  • 文章編號
  • 文章類型

輸入完後api的回傳值,理應會回傳

  • 文章標題
  • 文章內容
  • 作者名稱

如果今天我刻意隨便輸入一組亂數+英文的文章編號和文章類型

回傳狀態是200,並且回傳三個null欄位
這時前一個工程師的做法是判斷文章標題是否等於null
是的話就直接轉跳404頁面

if(this.aticeTitle == null) return this.$router.push({path:"/404"})

錯誤原因

  1. api製作時,沒有將Error狀態碼正確的回傳(如404、500等)
  2. 前端接資料時判斷是否404頁面作法不應該是取決於回傳值是否null,這樣容易出現bug

正確做法

後端將api正確處理後,會回傳Error訊息404或500等狀態碼

前端處理時使用asyncData()
在畫面渲染前先取得資料,並將資料傳入相對應的欄位

export default {
  asyncData ({ params, error }) {
    return axios.get(`https://my-api/posts/${params.id}`)
    .then((res) => {
      return { title: res.data.title }
    })
    .catch((e) => {
      error({ statusCode: 404, message: 'Post not found' })
    })
  }
}

這邊稍微提一下asyncData和fetch的差異
兩者很相似,都是在頁面(SSR)渲染前執行,但在對處理資料方式不同

  • asyncData()
    可以針對該(component)組件內的data作處理
  • fetch()
    可以對store(vuex)內資料作處理

更詳細請看這邊:nuxt - asyncData & fetch

之後在layouts製作一個error.vue

<template lang="pug">
div.page404.bg_half_pink
  div.W100
    img(src="~/assets/img/icon/f.svg")
    h3.f24 找不到頁面    
    img(src="~/assets/img/404-d.png")
    h6.f16.f_bold  oops 找不到此連結
      a(href="/")
            | 首頁
</template>
<script>
export default {
  layout:'error',
}
</script>

這邊要注意layout設定成error

export default {
  layout:'error'
}

當初用很久就是因為這個Error頁面沒有設定layout:'error'/images/emoticon/emoticon02.gif

所以整個的流程就是
當在asyncData()處理api時
若是報錯
error({ statusCode: 404, message: 'Post not found' })

因為在渲染前就攔截到有Eroor 的訊息
所以頁面將會自動跳到layout/error.vue
當然可以針對是404或500等狀態碼做相對應不同的頁面處理
這部分可以參考下方參考連結
參考來源:Custom Error Pages with nuxt.js

結語

這應該不太算是教學文
單純只是記錄一下自己踩得坑而已
雖然google大神有蠻多教學(英文QQ),官方文檔其實也有教學
但都覺得沒有很清楚(可能我理解能力差XD)
所以自己記錄一下
如果有說明錯誤的話請糾正我
也歡迎大家來討論/images/emoticon/emoticon41.gif


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言